package org.tron.trident.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.tron.trident.common.MessageResult;
import org.tron.trident.core.ApiWrapper;
import org.tron.trident.core.contract.Trc20Contract;
import org.tron.trident.core.exceptions.IllegalException;
import org.tron.trident.entity.Account;
import org.tron.trident.proto.Chain;
import org.tron.trident.proto.Response;
import org.tron.trident.service.AccountService;
import org.tron.trident.service.TRXService;
import org.tron.trident.service.Trc20Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/rpc")
public class TrxController {
    @Autowired
    private AccountService accountService;
    @Autowired
    private TRXService trxService;
    @Autowired
    private Trc20Service trc20Service;

    private Logger logger = LoggerFactory.getLogger(TrxController.class);

    //合约转账
    @GetMapping("/transfer")
    public String transfer() {
        ApiWrapper client = ApiWrapper.ofNile("42aa7174d122c27afee109e9e322e75475b8f7dc976e749a8c3e1a0e5758d298");

        org.tron.trident.core.contract.Contract contract = client.getContract("TYnGDru5gHob7JXJ8b5NKUFri3XiovT259");

        Trc20Contract token = new Trc20Contract(contract, "TNZML2UDQ7N6WCPeWzyGVPWE6DxGfek1VE", client);

        String txid = token.transfer("TXBkMPjX9YZcU2afVdRWKz9o9Z75ZPuNBb", 10, "memo", 1000000000L);

        return txid;

    }

    //trx转账
    @GetMapping("/transferTrx")
    public String transferTrx() throws IllegalException {
        ApiWrapper client = ApiWrapper.ofNile("42aa7174d122c27afee109e9e322e75475b8f7dc976e749a8c3e1a0e5758d298");
        Response.TransactionExtention result = client.transfer("TNZML2UDQ7N6WCPeWzyGVPWE6DxGfek1VE", "TXBkMPjX9YZcU2afVdRWKz9o9Z75ZPuNBb", 10000000);
        Chain.Transaction signedTransaction = client.signTransaction(result);
        String time = client.broadcastTransaction(signedTransaction);
        return time;
    }

    //生成地址
    @GetMapping("/generateAddress")
    public List<String> generateAddress() {
        return ApiWrapper.generateAddress();
    }


    //获取trc20代币余额
    @GetMapping("/getAccount")
    public String getAccount() {
        ApiWrapper client = ApiWrapper.ofNile("42aa7174d122c27afee109e9e322e75475b8f7dc976e749a8c3e1a0e5758d298");

        org.tron.trident.core.contract.Contract contract = client.getContract("TYnGDru5gHob7JXJ8b5NKUFri3XiovT259");

        Trc20Contract token = new Trc20Contract(contract, "TNZML2UDQ7N6WCPeWzyGVPWE6DxGfek1VE", client);
        BigInteger balance = token.balanceOf("TNZML2UDQ7N6WCPeWzyGVPWE6DxGfek1VE");
        return balance.toString();

    }


    /*获取一个新的trc20地址*/
    @GetMapping("address/{account}")
    public MessageResult getNewAddress(@PathVariable String account) {
        logger.info("create new account={}", account);
        try {
            String address;
            Account acct = accountService.findByName("TRX",account);
            if(acct != null){
                address = acct.getAddress();
                accountService.save(acct,"TRX");
            }
            else {
                address = trxService.createNewWallet(account);
            }
            MessageResult result = new MessageResult(0, "success");
            result.setData(address);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return MessageResult.error(500, "rpc error:" + e.getMessage());
        }
    }
    @GetMapping("withdraw")
    public MessageResult withdraw(String address, String amount,BigDecimal fee){
        logger.info("withdraw:address={},amount={},fee={}",address,amount,fee);
        BigDecimal arriveAmount = new BigDecimal(amount);
        try {
            MessageResult result = trc20Service.withdraw(address,arriveAmount.multiply(new BigDecimal("1000000")).longValue());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return MessageResult.error(500, "error:" + e.getMessage());
        }
    }

}
